﻿using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using Atendex.Containex;
using Atendex.Dominio.Interfaces;
using Atendex.Infraestrutura.Repositórios;
using Atendex.Web.AppCode;

namespace Atendex.Web
{
    public partial class CadastrarTipoSolicitacao : System.Web.UI.Page
    {
        private const string UnidadeNegocioIndex = "0";
        private const string CursoIndex = "1";

        protected void Page_Load(object sender, EventArgs e)
        {
            IGerente gerente = AtendexContext.GerenteAtual(this);
            if (gerente == null)
            {
                pnlCadastro.Visible = false;
                ShowMensagem("Você deve fazer o login como gerente antes de cadastrar um Tipo de Solicitação.");
                return;
            }

            if (!Page.IsPostBack)
            {
                CarregarTipos();
                CarregarUnidadesNegocios();
                CarregarTiposSolicitantes();

                pnlCadastro.Visible = true;
                lblMessage.Visible = false;
            }
            else
            {
                lblMessage.Visible = false;
            }
            CarregarGridComTipos();
        }

        private bool Editando
        {
            get
            {
                bool? editando = (bool?)ViewState["editando"];
                if (editando == null || editando == false)
                    return false;
                return true;
            }
            set
            {
                ViewState["editando"] = value;
                if (value)
                {
                    btnLimpar.Text = "Cancelar";
                    btnExcluir.Visible = true;
                }
                else
                {
                    btnLimpar.Text = "Limpar";
                    btnExcluir.Visible = false;
                }
            }
        }

        private ITipoSolicitacao ObjetoEditado
        {
            get
            {
                return (ITipoSolicitacao)ViewState["tipo_editado"];
            }
            set
            {
                ViewState["tipo_editado"] = value;
            }
        }

        private void CarregaEdicaoObjeto(ITipoSolicitacao objetoEdicao)
        {
            ObjetoEditado = objetoEdicao;
            Editando = true;

            txtNome.Text = objetoEdicao.Nome;
            txtDescricao.Text = objetoEdicao.Descricao;

            if (objetoEdicao is ITipoSolicitacaoAN)
            {
                ListBoxHelper.SelecionaItem(ddlTipo, UnidadeNegocioIndex);

                var un = (ITipoSolicitacaoAN)objetoEdicao;
                ListBoxHelper.SelecionaItem(ddlUnidadeNegocio, un.AreaNegocio.Id.ToString());
            }
            else if (objetoEdicao is ITipoSolicitacaoCurso)
            {
                ListBoxHelper.SelecionaItem(ddlTipo, CursoIndex);
            }

            IList<string> tiposSolicitantesIds = new List<string>();
            foreach (ITipoSolicitante tipoSolicitante in objetoEdicao.SolicitantesPermitidos)
            {
                tiposSolicitantesIds.Add(tipoSolicitante.Id.ToString());
            }

            ListBoxHelper.TransfereItemsDeLista(lstTiposSolicitantesDisponiveis,
                lstTiposSolicitantesEscolhidos, tiposSolicitantesIds);
            UpdateListTransferButtons();
        }

        private void CarregarGridComTipos()
        {
            var tiposAN = new RepositorioTipoSolicitacaoAN().ObtemTodos();
            gvTiposSolicitacaoAN.DataSource = tiposAN;
            gvTiposSolicitacaoAN.DataBind();
            ViewState["tipos_an"] = tiposAN;

            var tiposCurso = new RepositorioTipoSolicitacaoCurso().ObtemTodos();
            gvTiposSolicitacaoCurso.DataSource = tiposCurso;
            gvTiposSolicitacaoCurso.DataBind();
            ViewState["tipos_curso"] = tiposCurso;
        }

        private void CarregarTipos()
        {
            ddlTipo.Items.Add(new ListItem("Unidade de Negócio", UnidadeNegocioIndex)
                                                       {Selected = true});
            ddlTipo.Items.Add(new ListItem("Curso", CursoIndex));                                                   
        }

        private void CarregarTiposSolicitantes()
        {
            var repositorio = new RepositorioTipoSolicitante();
          
            lstTiposSolicitantesDisponiveis.DataSource = repositorio.ObtemTodos();
            lstTiposSolicitantesDisponiveis.DataTextField = "Nome";
            lstTiposSolicitantesDisponiveis.DataValueField = "Id";
            lstTiposSolicitantesDisponiveis.DataBind();
        }

        private void CarregarUnidadesNegocios()
        {
            var repositorio = new RepositorioUnidadeNegocio();
            ddlUnidadeNegocio.DataSource = repositorio.ObtemTodos();
            ddlUnidadeNegocio.DataTextField = "Nome";
            ddlUnidadeNegocio.DataValueField = "Id";
            ddlUnidadeNegocio.DataBind();
        }

        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            try
            {
                switch (ddlTipo.SelectedValue)
                {
                    case UnidadeNegocioIndex:
                        if (Editando)
                            AtualizarTipoAN();
                        else
                            SalvarTipoAN();
                        break;
                    case CursoIndex:
                        if (Editando)
                            AtualizarTipoCurso();
                        else
                            SalvarTipoCurso();
                        break;
                    default:
                        lblMessage.Text = "Tipo Solicitação não salvo. Tipo Inválido.";
                        return;
                }
                CarregarGridComTipos();

                if (Editando)
                {
                    lblMessage.Text = "Atualizado com sucesso.";
                    Editando = false;
                }
                else
                    lblMessage.Text = "Cadastro com sucesso.";

                LimpaCampos();
            }
            catch (Exception ex)
            {
                lblMessage.Text = ex.Message;
            }
            finally
            {
                lblMessage.Visible = true;
            }
        }

        private void SalvarTipoCurso()
        {
            var tipoCurso = Container.CriarTipoSolicitacaoCurso(txtNome.Text, txtDescricao.Text);

            PreencheTiposSolicitantesEscolhidos(tipoCurso);

            new RepositorioTipoSolicitacaoCurso().Salvar(tipoCurso);
        }

        private void AtualizarTipoCurso()
        {
            var tipoCurso = (ITipoSolicitacaoCurso) ObjetoEditado;
            tipoCurso.Nome = txtNome.Text;
            tipoCurso.Descricao = txtDescricao.Text;

            tipoCurso.SolicitantesPermitidos.Clear();
            PreencheTiposSolicitantesEscolhidos(tipoCurso);

            new RepositorioTipoSolicitacaoCurso().Salvar(tipoCurso);
        }

        private void SalvarTipoAN()
        {
            var repositorioUnidadeNegocio = new RepositorioUnidadeNegocio();
            int areaId = int.Parse(ddlUnidadeNegocio.SelectedValue);

            IUnidadeNegocio area = repositorioUnidadeNegocio.TentaObterPorId(areaId);

            var tipoAN = Container.CriarTipoSolicitacaoAN(txtNome.Text, txtDescricao.Text, area);

            PreencheTiposSolicitantesEscolhidos(tipoAN);

            new RepositorioTipoSolicitacaoAN().Salvar(tipoAN);
        }

        private void AtualizarTipoAN()
        {
            var repositorioUnidadeNegocio = new RepositorioUnidadeNegocio();
            int areaId = int.Parse(ddlUnidadeNegocio.SelectedValue);

            IUnidadeNegocio area = repositorioUnidadeNegocio.TentaObterPorId(areaId);

            ITipoSolicitacaoAN tipoAN = (ITipoSolicitacaoAN)ObjetoEditado;
            tipoAN.Nome = txtNome.Text;
            tipoAN.Descricao = txtDescricao.Text;
            tipoAN.AreaNegocio = area;

            tipoAN.SolicitantesPermitidos.Clear();
            PreencheTiposSolicitantesEscolhidos(tipoAN);

            new RepositorioTipoSolicitacaoAN().Salvar(tipoAN);
        }

        private void PreencheTiposSolicitantesEscolhidos(ITipoSolicitacao tipoSolicitacao)
        {
            var tipoSolicitanteRepositorio = new RepositorioTipoSolicitante();
            foreach (ListItem item in lstTiposSolicitantesEscolhidos.Items)
            {
                int tipoSolicitacaoId = int.Parse(item.Value);
                var tipoSolicitante = tipoSolicitanteRepositorio.ObtemPorId(tipoSolicitacaoId);
                tipoSolicitacao.SolicitantesPermitidos.Add(tipoSolicitante);
            }
        }

        protected void btnAddTipoSolicitante_Click(object sender, EventArgs e)
        {
            ListBoxHelper.TransfereListItems(lstTiposSolicitantesDisponiveis, lstTiposSolicitantesEscolhidos);
            UpdateListTransferButtons();
        }

        protected void btnRemoveTipoSolicitante_Click(object sender, EventArgs e)
        {
            ListBoxHelper.TransfereListItems(lstTiposSolicitantesEscolhidos, lstTiposSolicitantesDisponiveis);
            UpdateListTransferButtons();
        }

        private void UpdateListTransferButtons()
        {
            btnAddTipoSolicitante.Enabled =
                lstTiposSolicitantesDisponiveis.Items.Count > 0;
            btnRemoveTipoSolicitante.Enabled =
                lstTiposSolicitantesEscolhidos.Items.Count > 0;
        }

        private void ShowMensagem(string mensagem)
        {
            lblMessage.Text = mensagem;
            lblMessage.Visible = true;
        }

        protected static string ObtemTipo(ITipoSolicitacao tipo)
        {
            if (tipo is ITipoSolicitacaoAN)
            {
                return "UN";
            }
            if (tipo is ITipoSolicitacaoCurso)
            {
                return "Curso";
            }
            return "N/D";
        }

        protected void ddlTipo_SelectedIndexChanged(object sender, EventArgs e)
        {
            ddlUnidadeNegocio.Enabled = ddlTipo.SelectedValue.Equals(UnidadeNegocioIndex);
        }

        protected void gvTiposSolicitacaoAN_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            // commandargument parece vir sempre com o índice da linha que teve
            // o botão apertado
            int i = int.Parse((string)e.CommandArgument);

            var tipos = (ITipoSolicitacaoAN[]) ViewState["tipos_an"];
            ITipoSolicitacaoAN tipo = tipos[i];
            CarregaEdicaoObjeto(tipo);
        }

        protected void gvTiposSolicitacaoCurso_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            // commandargument parece vir sempre com o índice da linha que teve
            // o botão apertado
            int i = int.Parse((string)e.CommandArgument);
            ITipoSolicitacaoCurso tipo = ((ITipoSolicitacaoCurso[])ViewState["tipos_curso"])[i];
            CarregaEdicaoObjeto(tipo);
        }

        protected void btnLimpar_Click(object sender, EventArgs e)
        {
            LimpaCampos();
            Editando = false;
        }

        private void LimpaCampos()
        {
            txtNome.Text = string.Empty;
            txtDescricao.Text = string.Empty;
            ListBoxHelper.SelecionaItem(ddlTipo, UnidadeNegocioIndex);
            ddlUnidadeNegocio.Enabled = true;
            ListBoxHelper.TransfereTudo(lstTiposSolicitantesEscolhidos, lstTiposSolicitantesDisponiveis);
            UpdateListTransferButtons();
        }

        protected void btnExcluir_Click(object sender, EventArgs e)
        {
            try
            {
                if (ObjetoEditado is ITipoSolicitacaoAN)
                {
                    var repositorioTipoSolicitacaoAN = new RepositorioTipoSolicitacaoAN();
                    var tipo = (ITipoSolicitacaoAN)ObjetoEditado;
                    tipo.Ativo = false;
                    repositorioTipoSolicitacaoAN.Salvar(tipo);

                    Editando = false;
                    lblMessage.Text = "Tipo excluído com sucesso.";
                    lblMessage.Visible = true;
                }
                else if (ObjetoEditado is ITipoSolicitacaoCurso)
                {
                    var repositorioTipoSolicitacaoCurso = new RepositorioTipoSolicitacaoCurso();
                    var tipo = (ITipoSolicitacaoCurso) ObjetoEditado;
                    tipo.Ativo = false;
                    repositorioTipoSolicitacaoCurso.Salvar(tipo);

                    Editando = false;
                    lblMessage.Text = "Tipo excluído com sucesso.";
                    lblMessage.Visible = true;
                }
                LimpaCampos();
                CarregarGridComTipos();
            }
            catch (Exception)
            {
                lblMessage.Text = "Não foi possível excluir este tipo.";
                lblMessage.Visible = true;
            }
        }
    }
}
